package com.democode.auth.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.lang.Validator;
import com.demoCode.api.user.UserServiceClient;
import com.demoCode.common.common.ErrorCode;
import com.demoCode.common.exception.BusinessException;
import com.demoCode.model.auth.dto.AuthLoginDto;
import com.demoCode.model.auth.dto.AuthRegisterDto;
import com.demoCode.model.auth.dto.CheckCaptchaDto;
import com.demoCode.model.auth.vo.AuthCaptchaVo;
import com.demoCode.model.auth.vo.AuthLoginVo;
import com.democode.auth.service.AuthUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AuthUserServiceImpl implements AuthUserService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private UserServiceClient userServiceClient;

    private static final String CAPTCHA_KEY = "captcha:";

    /**
     * 用户登录
     * @param authLoginDto 登录请求体
     * @return 用户登录结果
     */
    @Override
    public AuthLoginVo userLogin(AuthLoginDto authLoginDto) {
        String phone = authLoginDto.getPhone();
        String password = authLoginDto.getPassword();
        log.info("用户请求登录，账号：{}，手机号：{}",phone,password);
        boolean isMobile = Validator.isMobile(phone);
        if(!isMobile){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"手机号格式不正确");
        }
        if (StringUtils.isAnyBlank(phone,password)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数不允许为空");
        }
        if(!checkCaptcha(authLoginDto.getCaptcha())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"验证码错误");
        }
        return userServiceClient.userLogin(authLoginDto);
    }

    /**
     * 用户注册
     * @param authRegisterDto 注册请求
     * @return 注册结果
     */
    @Override
    public Boolean userRegister(AuthRegisterDto authRegisterDto) {
        String phone = authRegisterDto.getPhone();
        String password = authRegisterDto.getPassword();
        String checkPassword = authRegisterDto.getCheckPassword();
        String nickname = authRegisterDto.getNickname();
        String address = authRegisterDto.getAddress();
        Integer age = authRegisterDto.getAge();
        Integer sex = authRegisterDto.getSex();
        // 校验参数
        if (StringUtils.isAnyBlank(phone,password,checkPassword,nickname)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"手机号，密码，昵称为必填项");
        }
        if (!password.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次输入的密码不一致");
        }
        if (phone.length() != 11){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"手机号应为11位");
        }
        if (password.length() > 13 || checkPassword.length() < 6){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码长度应在6-13位之间");
        }
        if(!checkCaptcha(authRegisterDto.getCaptcha())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"验证码错误");
        }
        return userServiceClient.userRegister(authRegisterDto);
    }

    /**
     * 获取验证码
     * @return
     */
    @Override
    public AuthCaptchaVo getCaptcha() {
        // 生成验证码uuid
        String uuid = UUID.randomUUID().toString();
        // 生成验证码
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(300, 100, 4, 4);
        // 获取验证码内容
        String code = captcha.getCode();
        // 获取验证码图片Base64
        String image = captcha.getImageBase64();
        // 将验证码存入Redis
        redisTemplate.opsForValue().set(CAPTCHA_KEY + uuid, code, 5, TimeUnit.MINUTES);
        // 返回验证码
        AuthCaptchaVo authCaptchaVo = new AuthCaptchaVo();
        authCaptchaVo.setUuid(uuid);
        authCaptchaVo.setImg(image);
        log.info("生成验证码：{}", code);
        return authCaptchaVo;
    }

    /**
     * 校验验证码
     * @param checkCaptchaDto
     * @return
     */
    @Override
    public Boolean checkCaptcha(CheckCaptchaDto checkCaptchaDto) {
        String code = checkCaptchaDto.getCode();
        String uuid = checkCaptchaDto.getUuid();
        // 校验验证码id是否存在
        Boolean flag = redisTemplate.hasKey(CAPTCHA_KEY + uuid);
        if (flag == null || !flag){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"验证码不存在");
        }
        // 获取redis中的答案
        String answer = redisTemplate.opsForValue().get(CAPTCHA_KEY + uuid);
        if (answer == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"验证码不存在");
        }
        // 删除验证码
        redisTemplate.delete(CAPTCHA_KEY + uuid);
        // 转换大小写
        code = code.toUpperCase();
        answer = answer.toUpperCase();
        // 比较验证码
        if (!answer.equals(code)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"验证码错误");
        }
        return true;
    }

    @Override
    public Boolean userLogout() {
        return userServiceClient.userLogout();
    }

}
